package gee

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/cookiejar"
	"os"
	"strings"
)

type Params struct {
	Username string
	Password string
	Link     string // 临时的URL
	Client_  *http.Client
	AllData  []byte
}

type ResponseJson struct {
	Success bool   `json:"success"`
	Message string `json:"message"`
	Data    Data   `json:"data"`
}
type EduLesson struct {
	CreateTime    string `json:"createTime"`
	UpdateTime    any    `json:"updateTime"`
	CreateBy      string `json:"createBy"`
	UpdateBy      any    `json:"updateBy"`
	TenantID      string `json:"tenantId"`
	LessonID      string `json:"lessonId"`
	Name          any    `json:"name"`
	TimeType      any    `json:"timeType"`
	LessonSum     any    `json:"lessonSum"`
	BeginTime     any    `json:"beginTime"`
	EndTime       any    `json:"endTime"`
	RankNo        any    `json:"rankNo"`
	StartLesson   int    `json:"startLesson"`
	EndLesson     int    `json:"endLesson"`
	PkID          string `json:"pkId"`
	IdentifyLabel string `json:"identifyLabel"`
}
type EduPlace struct {
	CreateTime     any    `json:"createTime"`
	UpdateTime     any    `json:"updateTime"`
	CreateBy       any    `json:"createBy"`
	UpdateBy       any    `json:"updateBy"`
	TenantID       any    `json:"tenantId"`
	PlaceID        any    `json:"placeId"`
	GroupID        any    `json:"groupId"`
	GroupName      any    `json:"groupName"`
	Sn             any    `json:"sn"`
	PlaceDirector  any    `json:"placeDirector"`
	PlaceNumber    any    `json:"placeNumber"`
	WorkStations   any    `json:"workStations"`
	PlaceName      any    `json:"placeName"`
	PlaceAlias     any    `json:"placeAlias"`
	SaleableArea   any    `json:"saleableArea"`
	BuildingArea   any    `json:"buildingArea"`
	PlaceProperty  any    `json:"placeProperty"`
	PlaceType      any    `json:"placeType"`
	PlaceNature    any    `json:"placeNature"`
	Status         any    `json:"status"`
	Remark         any    `json:"remark"`
	BuildingName   any    `json:"buildingName"`
	Floor          any    `json:"floor"`
	SchoolIDDic    any    `json:"schoolIdDic"`
	SchoolNameDic  any    `json:"schoolNameDic"`
	ManaGroupID    any    `json:"manaGroupId"`
	ManaGroupName  any    `json:"manaGroupName"`
	NameIncludeNum string `json:"nameIncludeNum"`
	ValidatorMsg   any    `json:"validatorMsg"`
	EduSchool      any    `json:"eduSchool"`
	PkID           any    `json:"pkId"`
	SchoolID       any    `json:"schoolId"`
	IdentifyLabel  any    `json:"identifyLabel"`
}
type EduTimeSchedule struct {
	CreateTime    any       `json:"createTime"`
	UpdateTime    any       `json:"updateTime"`
	CreateBy      any       `json:"createBy"`
	UpdateBy      any       `json:"updateBy"`
	TenantID      any       `json:"tenantId"`
	TimeScheID    string    `json:"timeScheId"`
	Type          any       `json:"type"`
	StartWeek     any       `json:"startWeek"`
	EndWeek       any       `json:"endWeek"`
	Week          any       `json:"week"`
	WeekList      any       `json:"weekList"`
	TeacherID     any       `json:"teacherId"`
	TeacherName   any       `json:"teacherName"`
	CourseID      any       `json:"courseId"`
	CourseName    any       `json:"courseName"`
	TclassID      any       `json:"tclassId"`
	TclassName    any       `json:"tclassName"`
	Status        any       `json:"status"`
	DetailType    any       `json:"detailType"`
	CheckStatus   any       `json:"checkStatus"`
	MainTeacherID any       `json:"mainTeacherId"`
	StopCourse    any       `json:"stopCourse"`
	CreateType    any       `json:"createType"`
	EduLesson     EduLesson `json:"eduLesson"`
	EduPlace      EduPlace  `json:"eduPlace"`
	CoursePeriod  int       `json:"coursePeriod"`
	CourseCredit  float64   `json:"courseCredit"`
	WeekDetail    any       `json:"weekDetail"`
	WeeklyHour    int       `json:"weeklyHour"`
	Examination   any       `json:"examination"`
	CoursePro     any       `json:"coursePro"`
	SemName       any       `json:"semName"`
	StuNum        any       `json:"stuNum"`
	PkID          string    `json:"pkId"`
	ScheID        any       `json:"scheId"`
	PlaceID       any       `json:"placeId"`
	LessonID      string    `json:"lessonId"`
	IdentifyLabel string    `json:"identifyLabel"`
}
type Schedule struct {
	CreateTime        string          `json:"createTime"`
	UpdateTime        any             `json:"updateTime"`
	CreateBy          string          `json:"createBy"`
	UpdateBy          any             `json:"updateBy"`
	TenantID          string          `json:"tenantId"`
	ScheInfoID        string          `json:"scheInfoId"`
	TeacherID         string          `json:"teacherId"`
	TeacherName       string          `json:"teacherName"`
	TclassID          string          `json:"tclassId"`
	TclassName        string          `json:"tclassName"`
	CourseID          string          `json:"courseId"`
	CourseName        string          `json:"courseName"`
	Date              string          `json:"date"`
	Week              int             `json:"week"`
	TaskID            string          `json:"taskId"`
	PlaceID           string          `json:"placeId"`
	SemID             string          `json:"semId"`
	LessonID          string          `json:"lessonId"`
	IsScheAuto        int             `json:"isScheAuto"`
	SchoolZoneID      string          `json:"schoolZoneId"`
	WeekOfDay         string          `json:"weekOfDay"`
	Status            string          `json:"status"`
	DetailType        any             `json:"detailType"`
	CheckStatus       any             `json:"checkStatus"`
	WhetherMain       string          `json:"whetherMain"`
	PlaceName         string          `json:"placeName"`
	ArrangeType       string          `json:"arrangeType"`
	Remarks           any             `json:"remarks"`
	WhetherTeacherLog string          `json:"whetherTeacherLog"`
	PracticeFlag      any             `json:"practiceFlag"`
	CreateType        any             `json:"createType"`
	IsNormal          any             `json:"isNormal"`
	ExceMsg           any             `json:"exceMsg"`
	AppID             any             `json:"appId"`
	EduTimeSchedule   EduTimeSchedule `json:"eduTimeSchedule"`
	OldTeacherID      any             `json:"oldTeacherId"`
	PkID              string          `json:"pkId"`
	IdentifyLabel     string          `json:"identifyLabel"`
}
type Data struct {
	Schedule []Schedule `json:"schedule"`
}

type Myinterface struct {
	Name        string `json:"name"`
	Week        string `json:"week"`
	Start       int    `json:"start"`
	End         int    `json:"end"`
	Placename   string `json:"placename"`
	Teachername string `json:"teachername"`
}
type CourseApi struct {
	Data []Myinterface `json:"data"`
	Code int           `json:"code"`
}

func newCourseApi() *CourseApi {
	return &CourseApi{
		Data: make([]Myinterface, 0, 100),
	}
}
func newMyinterface(name, placename, week, teachername string, start, end int) *Myinterface {
	return &Myinterface{
		Name:        name,
		Week:        week,
		Start:       start,
		End:         end,
		Placename:   placename,
		Teachername: teachername,
	}
}

func (api *CourseApi) add(myinterface Myinterface) {
	api.Data = append(api.Data, myinterface)
}

func newParams(Username, Password string, Client *http.Client) *Params {
	return &Params{
		Username: Username,
		Password: Password,
		Link:     fmt.Sprintf("username=%s&password=%s", Username, Password),
		Client_:  Client,
	}
}

func API(username, password string) *ResponseJson {
	//登录获取数据
	params := Course(username, password)
	response := new(ResponseJson)
	err := json.Unmarshal(params.AllData, response)
	CheckError(err)

	return response
}

func Api(username, password string) *CourseApi {

	//登录获取数据
	params := Course(username, password)

	//if params.AllData
	response := new(ResponseJson)
	err := json.Unmarshal(params.AllData, response)
	CheckError(err)

	//获取关键数据
	api := newCourseApi()
	schedules := response.Data.Schedule
	for k := range schedules {
		myinterface := newMyinterface(
			response.Data.Schedule[k].CourseName,
			response.Data.Schedule[k].PlaceName,
			response.Data.Schedule[k].WeekOfDay,
			response.Data.Schedule[k].TeacherName,
			response.Data.Schedule[k].EduTimeSchedule.EduLesson.StartLesson,
			response.Data.Schedule[k].EduTimeSchedule.EduLesson.EndLesson,
		)
		api.add(*myinterface)
	}
	return api
}
func Course(username, password string) *Params {
	// 获取全部的数据,返回一个结构体指针。
	jar, _ := cookiejar.New(nil)
	client := &http.Client{Jar: jar}
	params := newParams(username, password, client)
	params.Login()
	params.Request()

	return params
}

func (p *Params) Login() {
	var data = strings.NewReader(p.Link)
	req, err := http.NewRequest("POST", "http://aic.hbswkj.com:8080/jedu/login.do", data)
	CheckError(err)
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Accept", "*/*")
	req.Header.Set("X-Requested-With", "XMLHttpRequest")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
	req.Header.Set("Origin", "http://aic.hbswkj.com:8080")
	req.Header.Set("Referer", "http://aic.hbswkj.com:8080/jedu/login.jsp")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	resp, err := p.Client_.Do(req)
	CheckError(err)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)
	req, err = http.NewRequest("POST", "http://aic.hbswkj.com:8080/jedu/index.do", data)
	CheckError(err)
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Accept", "*/*")
	req.Header.Set("X-Requested-With", "XMLHttpRequest")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
	req.Header.Set("Origin", "http://aic.hbswkj.com:8080")
	req.Header.Set("Referer", "http://aic.hbswkj.com:8080/jedu/login.jsp")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	resp, err = p.Client_.Do(req)
	CheckError(err)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)

}

func (p *Params) Request() {
	var data = strings.NewReader(`week=23&semId=`)
	req, err := http.NewRequest("POST", "http://aic.hbswkj.com:8080/jedu/edu/core/eduScheduleInfo/getStudentWeekSchedule.do", data)
	CheckError(err)
	req.Header.Set("Connection", "keep-alive")
	req.Header.Set("Accept", "*/*")
	req.Header.Set("X-Requested-With", "XMLHttpRequest")
	req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36")
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
	req.Header.Set("Origin", "http://aic.hbswkj.com:8080")
	req.Header.Set("Referer", "http://aic.hbswkj.com:8080/jedu/edu/core/eduStudent/weekCourseTable.do?_t=529173&_winid=w9251")
	req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9")
	resp, err := p.Client_.Do(req)
	CheckError(err)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)
	bodyText, err := ioutil.ReadAll(resp.Body)
	CheckError(err)

	//handle error
	msg := `{code:403,msg:"登录失败,请检查账号和密码!"}`
	CheckError(err)
	if result := strings.Contains(string(bodyText), "登录失败"); result {
		fmt.Printf("%s\n", msg)
		os.Exit(0)

	} else {
		p.AllData = bodyText
	}

}

func Write(path string, data any) {
	/*
		path:路径
		data:结构体数据
	*/
	content, err := json.Marshal(data)
	CheckError(err)
	err = ioutil.WriteFile(path, content, 0777)
	CheckError(err)
}

func CheckError(err error) {
	if err != nil {
		log.Fatal(err)
	}
}
